﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Mime
{
    using System;
    using System.Collections.Generic;

    /// <summary>Processes a header field that contains references (message-IDs) to one or more other messages.
    /// </summary>
    internal sealed class ReferencesHeaderFieldBodyProcessor : HeaderFieldBodyProcessor
    {
        private readonly List<char> currentMessageId = new List<char>(128);
        private readonly ReferencesHeaderField result;

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal ReferencesHeaderFieldBodyProcessor(string fieldName)
        {
            this.result = new ReferencesHeaderField(fieldName);
        }

        internal sealed override void ProcessNormalBodyEvent(byte ev)
        {
            switch (ev)
            {
                case (byte)' ':
                case (byte)'\t':
                    break;
                case (byte)'<':
                    this.AddValueIfValid();
                    this.currentMessageId.Add((char)ev);
                    break;
                default:
                    this.currentMessageId.Add((char)ev);
                    break;
            }
        }

        internal sealed override void ProcessQuotedBodyEvent(byte ev, bool isQuoteChar)
        {
            // Quoting in references header fields is illegal, see http://www.rfc-editor.org/rfc/rfc5322.txt, 3.6.4.
            // The best we can do is to simply ignore it.
            if (!isQuoteChar)
            {
                this.ProcessNormalBodyEvent(ev);
            }
        }

        internal sealed override void ProcessCommentBodyEvent(byte ev)
        {
            // Deliberately empty: Ignore all comments
        }

        internal sealed override HeaderField GetHeaderField()
        {
            this.AddValueIfValid();
            return this.result;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void AddValueIfValid()
        {
            if (this.currentMessageId.Count > 0)
            {
                this.result.References.Add(new string(this.currentMessageId.ToArray()));
                this.currentMessageId.Clear();
            }
        }
    }
}
